﻿using System;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace AsynchronousMethods.Blocking
{
  public class Server
  {
    public void Serve (IPAddress address, int port)
    {
      ThreadPool.SetMinThreads (50, 50);    // Refer to Chapter 21
      ThreadPool.SetMaxThreads (50, 50);    // Refer to Chapter 21
      TcpListener listener = new TcpListener (address, port);
      listener.Start ();
      while (true)
      {
        TcpClient c = listener.AcceptTcpClient ();
        ThreadPool.QueueUserWorkItem (Accept, c);
      }
    }

    void Accept (object clientObject)
    {
      using (TcpClient client = (TcpClient)clientObject)
      using (NetworkStream n = client.GetStream ())
      {
        byte [] data = new byte [5000];

        int bytesRead = 0; int chunkSize = 1;
        while (bytesRead < data.Length && chunkSize > 0)
          bytesRead +=
            chunkSize = n.Read
              (data, bytesRead, data.Length - bytesRead);    // BLOCKS

        Array.Reverse (data);
        n.Write (data, 0, data.Length);                      // BLOCKS
      }
    }
  }
}
